package com.zenithmind.library.controller;

import com.zenithmind.common.result.PageResult;
import com.zenithmind.common.result.Result;
import com.zenithmind.library.pojo.dto.PublisherCreateDTO;
import com.zenithmind.library.pojo.dto.PublisherUpdateDTO;
import com.zenithmind.library.pojo.query.PublisherQuery;
import com.zenithmind.library.pojo.vo.PublisherVO;
import com.zenithmind.library.service.PublisherService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 出版社管理控制器
 * 
 * @author ZenithMind
 * @since 2024-06-14
 */
@Slf4j
@RestController
@RequestMapping("/api/zenithMind/v1/publishers")
@RequiredArgsConstructor
@Tag(name = "出版社管理", description = "出版社信息的增删改查操作")
public class PublisherController {

    private final PublisherService publisherService;

    @GetMapping
    @Operation(summary = "分页查询出版社", description = "根据条件分页查询出版社列表")
    @PreAuthorize("hasAuthority('library:publisher:query')")
    public Result<PageResult<PublisherVO>> getPublisherPage(@Valid PublisherQuery query) {
        log.info("分页查询出版社，查询条件：{}", query);
        PageResult<PublisherVO> result = publisherService.getPublisherPage(query);
        return Result.success(result);
    }

    @GetMapping("/{id}")
    @Operation(summary = "查询出版社详情", description = "根据ID查询出版社详细信息")
    @PreAuthorize("hasAuthority('library:publisher:query')")
    public Result<PublisherVO> getPublisherDetail(
            @Parameter(description = "出版社ID", required = true) @PathVariable String id) {
        log.info("查询出版社详情，ID：{}", id);
        PublisherVO result = publisherService.getPublisherDetail(id);
        return Result.success(result);
    }

    @PostMapping
    @Operation(summary = "创建出版社", description = "新增出版社信息")
    @PreAuthorize("hasAuthority('library:publisher:create')")
    public Result<PublisherVO> createPublisher(@Valid @RequestBody PublisherCreateDTO createDTO) {
        log.info("创建出版社，数据：{}", createDTO);
        return publisherService.createPublisher(createDTO);
    }

    @PutMapping("/{id}")
    @Operation(summary = "更新出版社", description = "更新出版社信息")
    @PreAuthorize("hasAuthority('library:publisher:update')")
    public Result<PublisherVO> updatePublisher(
            @Parameter(description = "出版社ID", required = true) @PathVariable String id,
            @Valid @RequestBody PublisherUpdateDTO updateDTO) {
        log.info("更新出版社，ID：{}，数据：{}", id, updateDTO);
        return publisherService.updatePublisher(id, updateDTO);
    }

    @DeleteMapping("/{id}")
    @Operation(summary = "删除出版社", description = "根据ID删除出版社")
    @PreAuthorize("hasAuthority('library:publisher:delete')")
    public Result<Void> deletePublisher(
            @Parameter(description = "出版社ID", required = true) @PathVariable String id) {
        log.info("删除出版社，ID：{}", id);
        return publisherService.deletePublisher(id);
    }

    @DeleteMapping("/batch")
    @Operation(summary = "批量删除出版社", description = "根据ID列表批量删除出版社")
    @PreAuthorize("hasAuthority('library:publisher:delete')")
    public Result<Void> batchDeletePublishers(@RequestBody List<String> ids) {
        log.info("批量删除出版社，IDs：{}", ids);
        return publisherService.batchDeletePublishers(ids);
    }

    @PutMapping("/{id}/enable")
    @Operation(summary = "启用出版社", description = "将出版社设置为启用状态")
    @PreAuthorize("hasAuthority('library:publisher:update')")
    public Result<Void> enablePublisher(
            @Parameter(description = "出版社ID", required = true) @PathVariable String id) {
        log.info("启用出版社，ID：{}", id);
        return publisherService.enablePublisher(id);
    }

    @PutMapping("/{id}/disable")
    @Operation(summary = "禁用出版社", description = "将出版社设置为禁用状态")
    @PreAuthorize("hasAuthority('library:publisher:update')")
    public Result<Void> disablePublisher(
            @Parameter(description = "出版社ID", required = true) @PathVariable String id) {
        log.info("禁用出版社，ID：{}", id);
        return publisherService.disablePublisher(id);
    }

    @GetMapping("/name/{name}")
    @Operation(summary = "根据名称查询出版社", description = "根据出版社名称查询出版社信息")
    @PreAuthorize("hasAuthority('library:publisher:query')")
    public Result<List<PublisherVO>> getPublishersByName(
            @Parameter(description = "出版社名称", required = true) @PathVariable String name) {
        log.info("根据名称查询出版社，名称：{}", name);
        List<PublisherVO> result = publisherService.getPublishersByName(name);
        return Result.success(result);
    }

    @GetMapping("/code/{code}")
    @Operation(summary = "根据编码查询出版社", description = "根据出版社编码查询出版社信息")
    @PreAuthorize("hasAuthority('library:publisher:query')")
    public Result<PublisherVO> getPublisherByCode(
            @Parameter(description = "出版社编码", required = true) @PathVariable String code) {
        log.info("根据编码查询出版社，编码：{}", code);
        PublisherVO result = publisherService.getPublisherByCode(code);
        return Result.success(result);
    }

    @GetMapping("/search")
    @Operation(summary = "搜索出版社", description = "根据关键词搜索出版社")
    @PreAuthorize("hasAuthority('library:publisher:query')")
    public Result<List<PublisherVO>> searchPublishers(
            @Parameter(description = "搜索关键词", required = true) @RequestParam String keyword,
            @Parameter(description = "限制数量") @RequestParam(defaultValue = "10") Integer limit) {
        log.info("搜索出版社，关键词：{}，限制数量：{}", keyword, limit);
        List<PublisherVO> result = publisherService.searchPublishers(keyword, limit);
        return Result.success(result);
    }

    @GetMapping("/hot")
    @Operation(summary = "获取热门出版社", description = "获取热门出版社列表")
    public Result<List<PublisherVO>> getHotPublishers(
            @Parameter(description = "限制数量") @RequestParam(defaultValue = "10") Integer limit) {
        log.info("获取热门出版社，限制数量：{}", limit);
        List<PublisherVO> result = publisherService.getHotPublishers(limit);
        return Result.success(result);
    }

    @GetMapping("/country/{country}")
    @Operation(summary = "根据国家查询出版社", description = "根据国家查询出版社列表")
    @PreAuthorize("hasAuthority('library:publisher:query')")
    public Result<List<PublisherVO>> getPublishersByCountry(
            @Parameter(description = "国家", required = true) @PathVariable String country) {
        log.info("根据国家查询出版社，国家：{}", country);
        List<PublisherVO> result = publisherService.getPublishersByCountry(country);
        return Result.success(result);
    }

    @GetMapping("/city/{city}")
    @Operation(summary = "根据城市查询出版社", description = "根据城市查询出版社列表")
    @PreAuthorize("hasAuthority('library:publisher:query')")
    public Result<List<PublisherVO>> getPublishersByCity(
            @Parameter(description = "城市", required = true) @PathVariable String city) {
        log.info("根据城市查询出版社，城市：{}", city);
        List<PublisherVO> result = publisherService.getPublishersByCity(city);
        return Result.success(result);
    }

    @PutMapping("/{id}/book-count")
    @Operation(summary = "更新出版社图书数量", description = "重新统计并更新出版社的图书数量")
    @PreAuthorize("hasAuthority('library:publisher:update')")
    public Result<Void> updatePublisherBookCount(
            @Parameter(description = "出版社ID", required = true) @PathVariable String id) {
        log.info("更新出版社图书数量，出版社ID：{}", id);
        return publisherService.updatePublisherBookCount(id);
    }

    @PutMapping("/{id}/book-count/increment")
    @Operation(summary = "增加出版社图书数量", description = "增加出版社的图书数量")
    @PreAuthorize("hasAuthority('library:publisher:update')")
    public Result<Void> incrementPublisherBookCount(
            @Parameter(description = "出版社ID", required = true) @PathVariable String id) {
        log.info("增加出版社图书数量，出版社ID：{}", id);
        return publisherService.incrementPublisherBookCount(id);
    }

    @PutMapping("/{id}/book-count/decrement")
    @Operation(summary = "减少出版社图书数量", description = "减少出版社的图书数量")
    @PreAuthorize("hasAuthority('library:publisher:update')")
    public Result<Void> decrementPublisherBookCount(
            @Parameter(description = "出版社ID", required = true) @PathVariable String id) {
        log.info("减少出版社图书数量，出版社ID：{}", id);
        return publisherService.decrementPublisherBookCount(id);
    }

    @GetMapping("/check/code/{code}")
    @Operation(summary = "检查出版社编码", description = "检查出版社编码是否已存在")
    @PreAuthorize("hasAuthority('library:publisher:query')")
    public Result<Boolean> checkPublisherCode(
            @Parameter(description = "出版社编码", required = true) @PathVariable String code,
            @Parameter(description = "排除的出版社ID") @RequestParam(required = false) String excludeId) {
        log.info("检查出版社编码，编码：{}，排除ID：{}", code, excludeId);
        boolean exists = publisherService.existsByCode(code, excludeId);
        return Result.success(!exists);
    }

    @GetMapping("/check/name/{name}")
    @Operation(summary = "检查出版社名称", description = "检查出版社名称是否已存在")
    @PreAuthorize("hasAuthority('library:publisher:query')")
    public Result<Boolean> checkPublisherName(
            @Parameter(description = "出版社名称", required = true) @PathVariable String name,
            @Parameter(description = "排除的出版社ID") @RequestParam(required = false) String excludeId) {
        log.info("检查出版社名称，名称：{}，排除ID：{}", name, excludeId);
        boolean exists = publisherService.existsByName(name, excludeId);
        return Result.success(!exists);
    }

    @PostMapping("/import")
    @Operation(summary = "导入出版社数据", description = "批量导入出版社数据")
    @PreAuthorize("hasAuthority('library:publisher:import')")
    public Result<String> importPublishers(@RequestBody List<PublisherCreateDTO> publishers) {
        log.info("导入出版社数据，数量：{}", publishers.size());
        return publisherService.importPublishers(publishers);
    }

    @GetMapping("/export")
    @Operation(summary = "导出出版社数据", description = "导出出版社数据到Excel文件")
    @PreAuthorize("hasAuthority('library:publisher:export')")
    public Result<String> exportPublishers(@Valid PublisherQuery query) {
        log.info("导出出版社数据，查询条件：{}", query);
        return publisherService.exportPublishers(query);
    }
}
